<template>
  <div class="container">
    <!-- 流程图 -->
    <!-- <div class="config-pic">
      <el-image style="width: 100px; height: 100px" :src="flowChartUrl" :preview-src-list="[flowChartUrl]">
      </el-image>
    </div> -->
    <div class="config-content">
      <!-- 1、选择环境 -->
      <el-divider>选择环境</el-divider>
      <div class="config-item">
        <span>选择环境：</span>
        <el-select v-model="curEnv" placeholder="请选择" filterable @change="envChange">
          <el-option v-for="item in envList" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </div>
      <!-- 平台层操作开始 -->
      <!-- 2、登录平台账号 -->
      <!-- 3、拉取全量菜单 -->
      <!-- 是否显示菜单全量数据 -->
      <el-divider>平台层</el-divider>
      <div class="config-item">
        <span>全量菜单table：</span><el-switch v-model="showTable" active-color="#67C23A"></el-switch>
      </div>
      <el-divider></el-divider>
      <div v-show="showTable">
        <div class="config-item">
          <span>搜索菜单：</span>
          <el-input v-model="menuName" @input="getMenuList" placeholder="请输入"></el-input>
        </div>
        <el-table :data="tableData" height="300" style="width: 100%;margin-bottom: 20px;" row-key="id" border
          default-expand-all :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" v-loading="loading">
          <el-table-column prop="menuName" label="菜单名称">
          </el-table-column>
          <el-table-column prop="path" label="URL">
          </el-table-column>
          <el-table-column prop="categoryName" label="类型">
          </el-table-column>
          <el-table-column prop="parentName" label="上级菜单">
          </el-table-column>
        </el-table>
        <el-divider></el-divider>
      </div>
      <!-- 4、配置菜单 -->
      <!-- 是否显示菜单form -->
      <div class="config-item">
        <span>菜单form：</span><el-switch v-model="showForm" active-color="#67C23A"></el-switch>
      </div>
      <el-divider></el-divider>
      <template v-if="showForm">
        <el-form ref="form" :model="groupForm" label-width="100px" label-position="right" inline>
          <div v-for="(item, index) in groupForm.list" :key="index">
            <!-- <el-button type="success" style="margin-bottom:10px;">{{ categoryObj[index] }}</el-button> -->
            <el-card class="box-card">
              <div slot="header" class="clearfix">
                <el-descriptions :title="categoryObj[index]"> </el-descriptions>
              </div>
              <div v-for="(son, idx) in item" :key="idx">
                <!-- 按钮没有所属应用 -->
                <el-form-item label="所属应用" v-if="index !== 2" :prop="`list[${index}][${idx}].appId`" :rules="rules.appId">
                  <el-select v-model="son.appId" placeholder="请选择" filterable>
                    <el-option v-for="item in appOptions" :key="item.value" :label="item.label" :value="item.value">
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="所属模块" :prop="`list[${index}][${idx}].topMenuId`" :rules="rules.topMenuId">
                  <el-select v-model="son.topMenuId" placeholder="请选择" filterable
                    @change="getMenuTreeData($event, index, idx, son.category, son.topMenuId)">
                    <el-option v-for="item in topMenuOptions" :key="item.id" :label="item.topMenuName" :value="item.id">
                    </el-option>
                  </el-select>
                </el-form-item>
                <el-form-item label="菜单名称" :prop="`list[${index}][${idx}].menuName`" :rules="rules.menuName">
                  <el-input v-model="son.menuName" placeholder="请输入" maxlength="10" show-word-limit></el-input>
                </el-form-item>
                <el-form-item label="菜单编号" :prop="`list[${index}][${idx}].menuCode`" :rules="rules.menuCode">
                  <el-input v-model="son.menuCode" placeholder="请输入"></el-input>
                </el-form-item>
                <el-form-item label="上级菜单">
                  <tree-select v-model="son.parentId" :filterable="true" :data="son.menuTreedata" clearable
                    :props="defaultProps"></tree-select>
                </el-form-item>
                <!-- 只有菜单有URL -->
                <el-form-item label="URL" v-if="index === 1" :rules="rules.path" :prop="`list[${index}][${idx}].path`">
                  <el-input v-model="son.path" placeholder="请输入"></el-input>
                </el-form-item>
                <!-- <el-form-item label="菜单顺序" :rules="rules.sort" :prop="`list[${index}][${idx}].sort`">
                  <el-input v-model="son.sort" placeholder="请输入"></el-input>
                </el-form-item> -->
                <el-form-item label="">
                  <el-button type="primary" class="row-del" @click="handleCopy(index, idx)">复制</el-button>
                </el-form-item>
                <el-form-item label="">
                  <el-button type="danger" class="row-del" @click="handleDel(index, idx)">删除</el-button>
                </el-form-item>
                <el-divider></el-divider>
              </div>
              <div class="config-item center">
                <el-button type="success" @click="handleAdd(index)">继续新增</el-button>
              </div>
            </el-card>
            <el-divider></el-divider>
          </div>
        </el-form>
        <div class="config-item center">
          <el-button type="primary" @click="addMenu">提交菜单</el-button>
        </div>
        <el-divider></el-divider>
      </template>
      <!-- 5、同步租户 -->
      <div class="config-item">
        <span>选择同步租户：</span>
        <el-select v-model="tenantId" placeholder="请选择" filterable @change="syncTenant">
          <el-option v-for="item in tenantList" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </div>
      <!-- 手动同步租户 -->
      <!-- <div class="config-item">
        <span>手动同步租户：</span>
        <el-button type="primary" @click="syncTenant()">同步租户</el-button>
      </div>
      <el-divider></el-divider> -->
      <!-- 平台层操作结束 -->

      <!-- 综合平台操作开始 -->
      <!-- <div class="config-item">
        <span>手动操作综合平台</span><el-switch v-model="autoNext" @change="managePlatLogin(true)"
          active-color="#67C23A"></el-switch>
      </div>
      <el-divider></el-divider> -->
      <!-- 6、获取综合平台验证码 -->
      <!-- 是否显示手动输入验证码 -->
      <el-divider>综合管理平台</el-divider>
      <div class="config-item">
        <span>手输验证码登录综合平台：</span><el-switch v-model="showCaptcha" @change="refreshCaptcha"
          active-color="#67C23A"></el-switch>
      </div>
      <div class="config-item center" v-show="showCaptcha">
        <img :src="captchaCodeObj.captchaCodeUrl" @click="refreshCaptcha" style="cursor: pointer;" />
        <el-input v-model="captchaCodeObj.captchaCode" @keyup.enter.native="managePlatLogin(false)"
          placeholder="请输入验证码"></el-input>
      </div>
      <el-divider></el-divider>
      <!-- 7、登录综合平台账号 -->
      <!-- 8、获取licence列表 -->
      <div class="config-item">
        <span>licence列表：</span><el-switch v-model="showLicence" active-color="#67C23A"></el-switch>
      </div>
      <el-divider></el-divider>
      <!-- 是否显示licence列表 -->
      <div v-show="showLicence">
        <div class="config-item">
          <span>授权企业：</span>
          <el-input v-model="enterpriseName" @input="getLicenceList" placeholder="请输入"></el-input>
        </div>
        <el-table :data="licenceList" height="300" style="width: 100%;margin-bottom: 20px;" row-key="id" border>
          <el-table-column prop="enterpriseName" label="授权企业">
          </el-table-column>
          <el-table-column prop="authorizeCode" label="授权编码">
          </el-table-column>
          <el-table-column prop="startTime" label="授权开始时间">
          </el-table-column>
          <el-table-column prop="endTime" label="授权结束时间">
          </el-table-column>
          <el-table-column prop="" label="查看产品">
            <template slot-scope="{row}">
              <el-button type="text" class="el-icon-view" @click="onProductInfo(row.id)">查看产品（数量{{ row.productCount
              }}）</el-button>
            </template>
          </el-table-column>
          <el-table-column prop="" label="操作">
            <template slot-scope="{row}">
              <el-button type="text" class="el-icon-download" @click="onDown(row.id)">下载授权文件</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 查看产品 -->
        <ProductInfo ref="refProductInfo" :checkedNodes="checkedProduct">
        </ProductInfo>
        <el-divider></el-divider>
      </div>
      <!-- 9、获取产品列表 -->
      <div class="config-item">
        <span>选择产品：</span>
        <el-select v-model="productId" placeholder="请选择" filterable @change="asyncNewMenu">
          <el-option v-for="item in productList" :key="item.id" :label="item.productName" :value="item.id"></el-option>
        </el-select>
      </div>

      <!-- <el-divider></el-divider>
      <div class="config-item">
        <span>手动停止定时器：</span>
        <el-button type="primary" @click="clearTimer">停止查询</el-button>
      </div> -->

      <!-- 10、获取产品绑定的菜单code集合 -->
      <!-- 11、轮询菜单是否被同步成功 -->
      <!-- 12、同步菜单 -->
      <!-- 13、添加菜单codes到产品 -->
      <!-- 14、在licence列表中找到对应租户下载licence授权文件 -->
      <!-- 综合平台操作结束 -->
    </div>
    <div class="config-btns">
      <el-button type="primary" @click="showLog">日志</el-button>
    </div>
    <div v-show="logFlag" class="draggable" :style="{ top: posY + 'px', left: posX + 'px' }" @mousedown="startDragging"
      @mousemove="dragging" @mouseup="stopDragging">
      <div class="hide-btns">
        <el-button type="plain" @click="clearLog">清空</el-button>
        <el-button type="danger" @click="showLog">关闭</el-button>
      </div>
      <div class="log-content">
        <div class="log-plat">
          <div class="log-title">平台层操作日志</div>
          <div class="log-main">
            <div v-for="(item, index) in platLogList" :key="index + item">{{ index + 1 }}：{{ item }}</div>
          </div>
        </div>
        <div class="log-manage">
          <div class="log-title">综合平台操作日志</div>
          <div class="log-main">
            <div v-for="(item, index) in manageLogList" :key="index + item">{{ index + 1 }}：{{ item }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import qs from 'qs';
import dayjs from 'dayjs';
import website from '@/util/config';
import { setToken } from "@/util/auth";
import TreeSelect from './tree-select.vue';
import ProductInfo from "./productInfo.vue";
import { createWorker } from 'tesseract.js';

export default {
  name: 'mainPage',
  components: {
    TreeSelect,
    ProductInfo,
  },
  data() {
    return {
      flowChartUrl: '/tip.png',
      logFlag: true, // 是否显示日志弹窗
      dragFlag: false,  // 是否正在拖拽
      offsetX: 0, // 鼠标按下时距离元素左上角的偏移
      offsetY: 0,
      posX: 800, // 元素左上角相对于父元素的位置
      posY: 600,
      windowX: 0, // window可视区域宽度
      windowY: 0, // window可视区域宽度
      dragWidth: 0, // 可拖拽容器宽度
      dragHeight: 0, // 可拖拽容器高度
      website,
      curEnv: '', // 当前环境
      envList: website.envList, // 环境列表
      platLogList: [], //平台层操作日志列表
      manageLogList: [], //综合平台层操作日志列表
      tenantId: '', //租户id
      tenantList: [], //租户列表
      menuName: '', //搜索菜单名称
      showTable: false, //是否显示菜单table
      loading: false, //菜单table加载中
      categoryObj: { //菜单类型
        0: '菜单组',
        1: '菜单',
        2: '按钮'
      },
      tableData: [], //菜单table数据
      showForm: false,
      tempForm: {
        category: 0,//类型
        appId: '',//所属应用
        topMenuId: '',//所属模块
        menuName: '',//菜单名称
        menuCode: '',//菜单编号
        parentId: '',//上级菜单
        path: '',//URL
        sort: '',//菜单顺序
        isShow: 1,//是否显示
        appSource: '',//菜单图标
        tenantTypes: ['NORMAL'], //可用租户类型 NORMAL普通租户 GROUP集团租户 PLATFORM_ADMIN管理租户
        favoriteImgId: '',//收藏图标
        favoriteName: '',//收藏名称
        favoriteOpenMode: 0,//页面打开方式
      },
      groupForm: { //菜单组
        list: [
          [{}], [{}], [{}]
        ],
      },
      appOptions: [],//所属应用列表
      topMenuOptions: [],//所属模块列表
      defaultProps: { //上级菜单树形结构配置
        children: 'children',
        label: 'menuName'
      },
      rules: {
        appId: [
          { required: true, message: '请选择所属应用', trigger: 'blur' }
        ],
        topMenuId: [
          { required: true, message: '请选择所属模块', trigger: 'blur' }
        ],
        menuName: [
          { required: true, message: '请输入菜单名称', trigger: 'blur' }
        ],
        menuCode: [
          { required: true, message: '请输入菜单编号', trigger: 'blur' }
        ],
        path: [
          { required: true, message: '请输入URL', trigger: 'blur' }
        ],
        sort: [
          { required: true, message: '请输入菜单顺序', trigger: 'blur' }
        ]
      },
      platApiPre: '/devPlat', // 平台前缀
      manageApiPre: '/devManage',// 综合平台前缀
      autoNext: false,
      captchaCodeObj: {
        captchaCode: '',//验证码
        uuid: '', //验证码uuid
        captchaCodeUrl: '', //验证码图片地址
      },
      showCaptcha: false, // 是否显示手动输入验证码
      tryCount: 5, // 验证码失败尝试次数
      productId: '', // 产品id
      showLicence: false, // 是否展示licence列表
      enterpriseName: '', // 授权企业名称
      licenceList: [], //licence列表
      checkedProduct: [], // 选中产品
      productList: [], // 产品下拉
      menuTimer: null, // 查询菜单定时器
      newMenuCodes: [], // 新增菜单code集合
      bindMenuCodes: [], // 产品绑定的菜单code集合
    };
  },
  mounted() {
    let dragDom = document.querySelector('.draggable').getBoundingClientRect();
    this.windowX = window.innerWidth;
    this.windowY = window.innerHeight;
    this.dragWidth = dragDom.width;
    this.dragHeight = dragDom.height;
  },
  methods: {
    // 切换日志弹窗
    showLog() {
      this.logFlag = !this.logFlag;
    },
    // 清空日志
    clearLog() {
      this.platLogList = [];
      this.manageLogList = [];
    },
    // 登录平台账号
    envChange() {
      if (this.curEnv) {
        Object.assign(this.$data, this.$options.data.call(this), { curEnv: this.curEnv });
        this.platApiPre = this.envList.find(item => item.value === this.curEnv).type === 'dev' ? '/devPlat' : '/testPlat';
        this.manageApiPre = this.envList.find(item => item.value === this.curEnv).type === 'dev' ? '/devManage' : '/testManage';
      }
      // 登录平台
      this.normalPlatLogin();
      // 登录综合平台
      this.managePlatLogin(true);
    },
    // 登录平台
    normalPlatLogin() {
      let jsonData = {
        username: this.website.userName,
        password: this.website.password,
        uuid: '',
        captchaCode: '',
        tenantId: '000000',
        grant_type: 'password',
        scope: 'all',
        type: 'account',
        hideErrorMsg: true,
      };
      this.$request({
        url: `${this.platApiPre}/api/tiji-auth/oauth/token`,
        method: 'post',
        data: qs.stringify(jsonData),
      })
        .then(res => {
          // 设置token
          this.platLogList.push('成功登录平台');
          setToken('plat-token', res.data.access_token);
          // 拉取租户
          this.getTenantList();
          // // 拉取菜单
          this.getMenuList();
          // 获取所属应用
          this.getAppOptions();
          // 获取所属模块
          this.getTopMenuOptions();
        });
    },
    //  获取租户列表
    getTenantList() {
      this.$request.get(`${this.platApiPre}/api/tiji-system/base-info?domain=${this.curEnv}`).then(res => {
        this.tenantList = res.data.data.tenantOptions;
        this.platLogList.push('成功获取租户列表');
      });
    },

    // 同步租户
    syncTenant() {
      this.$request({
        url: `${this.platApiPre}/api/tiji-system/tenant/increment-add-menus`,
        method: 'post',
        data: qs.stringify({
          orgCode: '000',
          tenantId: this.tenantId
        })
      }).then(() => {
        this.getMenuList();
        this.platLogList.push('成功同步租户');
      });
    },

    // 拉取菜单
    getMenuList() {
      this.loading = true;
      this.tableData = [];
      let getData = {
        params: {
          displayClient: 1,
          category: '',
          menuName: this.menuName
        }
      };
      this.$request.get(`${this.platApiPre}/api/tiji-system/menu/tree`, getData).then(res => {
        this.tableData = res.data.data;
        this.recursion(this.tableData);
        this.platLogList.push('成功拉取全量菜单');
      }).finally(() => {
        this.loading = false;
      });
    },
    // 删除hasChildren字段，否则树形表格渲染不出来, 类型赋值
    recursion(data = []) {
      if (data.length) {
        data.forEach((element) => {
          element.categoryName = this.categoryObj[element.category];
          delete element.hasChildren;
          if ("children" in element) {
            element.categoryName = this.categoryObj[element.category];
            this.recursion(element.children);
          }
        });
      }
    },

    // 获取所属应用
    getAppOptions() {
      this.$request.get(`${this.platApiPre}/api/tiji-system/app/option`).then(res => {
        this.appOptions = res.data.data;
        this.platLogList.push('成功拉取所属应用');
      });
    },
    // 获取所属模块
    getTopMenuOptions() {
      this.$request.get(`${this.platApiPre}/api/tiji-system/menu/top-menu`).then(res => {
        //去除驾驶舱的 isBuiltIn=1 position=1
        this.topMenuOptions = res.data.data.filter(
          (item) => item.isBuiltIn !== 1 && item.position !== 1
        );
        this.platLogList.push('成功拉取所属模块');
      });
    },
    // 获取上级菜单
    getMenuTreeData(e, idx, idx1, category, topMenuId) {
      // const categoryTemp = this.toInt(category);
      // const categoryList = categoryTemp != 2 ? [0] : [0, 1];
      let getData = {
        params: {
          topMenuId: topMenuId,
          displayClient: 1,
          categoryList: [0, 1],
        },
        paramsSerializer: (p) => {
          const s = p.categoryList.map(item => `categoryList=${item}`).join('&');
          return p.topMenuId ? `topMenuId=${p.topMenuId}&displayClient=${p.displayClient}&${s}` : `displayClient=${p.displayClient}&${s}`;
        }
      };
      this.$request.get(`${this.platApiPre}/api/tiji-system/menu/top-menu/tree`, getData).then(res => {
        this.$set(this.groupForm.list[idx][idx1], 'menuTreedata', res.data.data);
        this.platLogList.push('成功拉取上级菜单');
      });
    },
    // 上级菜单选中
    handleNodeClick(e, idx) {
      this.groupForm.list[idx].parentId = e.id;
    },
    toInt(val, defaultValue) {
      if (this.isEmpty(val)) {
        return defaultValue === undefined ? -1 : defaultValue;
      }
      const num = parseInt(val, 0);
      return Number.isNaN(num) ? (defaultValue === undefined ? -1 : defaultValue) : num;
    },
    isEmpty(val) {
      if (
        val === null ||
        typeof val === 'undefined' ||
        (typeof val === 'string' && val === '' && val !== 'undefined')
      ) {
        return true;
      }
      return false;
    },
    // 新增菜单
    handleAdd(idx) {
      this.groupForm.list[idx].push({
        ...this.tempForm,
        category: idx,
      });
    },
    // 复制菜单
    handleCopy(idx, idx1) {
      let copyData = JSON.parse(JSON.stringify(this.groupForm.list[idx][idx1]));
      // 指定位置插入
      this.groupForm.list[idx].splice(idx1, 0, copyData);
      // 末尾位置插入
      // this.groupForm.list[idx].push(copyData)
    },
    // 删除菜单
    handleDel(idx, idx1) {
      this.groupForm.list[idx].splice(idx1, 1);
    },
    // 并发请求
    formatterFn() {
      let failPostDataList = [];
      let failIdxs = [];
      let reqList = [];
      this.groupForm.list.map((v, idx) => {
        if (v[0]) {
          v.map(item => {
            let postData = {
              ...this.tempForm,
              category: idx,
              ...item,
            };
            failPostDataList.push(postData);
            reqList.push(this.$request.post(`${this.platApiPre}/api/tiji-system/menu`, { ...postData, menuTreedata: null }));
          });
        }
      });
      Promise.allSettled(reqList).then(results => {
        this.groupForm.list = [[], [], []];
        let errMsgs = [];
        results.forEach((result, index) => {
          // 错误提示
          if (result.status === 'rejected') {
            errMsgs.push(result.reason.msg);
            failIdxs.push(index);
          }
        });
        failPostDataList.map((v, idx) => {
          if (failIdxs.includes(idx)) {
            this.groupForm.list[v.category].push(v);
          } else {
            this.platLogList.push(`${this.captchaCodeObj[v.category]}：${v.menuName}新增成功`);
            this.newMenuCodes.push(v.menuCode);
          }
        });
        this.platLogList = this.platLogList.concat(errMsgs);
      });
    },
    // 提交菜单
    addMenu() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.formatterFn();
        }
      });
    },

    // -----------综合平台模块分界线----------
    // 登录综合平台
    async managePlatLogin(auto) {
      this.clearTimer();
      let initCount = this.$options.data().tryCount;
      // auto 是否自动登录
      if (auto) {
        let captchaTxt = '开始获取验证码';
        // 获取验证码
        if (this.tryCount != this.$options.data().tryCount) {
          captchaTxt = `第${initCount - this.tryCount}次重新获取验证码`;
        }
        this.manageLogList.push(captchaTxt);
        this.captchaCodeObj = await this.getCaptcha();
        this.manageLogList.push(`验证码识别成功：${this.captchaCodeObj.captchaCode}`);
      }
      let jsonData = {
        username: this.website.userName,
        password: this.website.password,
        uuid: this.captchaCodeObj.uuid,
        captchaCode: this.captchaCodeObj.captchaCode,
        grant_type: 'password',
        scope: 'all',
      };
      this.$request({
        url: `${this.manageApiPre}/api/tiji-auth/oauth/token`,
        method: 'post',
        data: qs.stringify(jsonData),
      })
        .then(res => {
          this.manageLogList.push('成功登录综合平台');
          // 设置token
          setToken('manage-token', res.data.access_token);
          // 获取licence列表
          this.getLicenceList();
          // 获取产品列表
          this.getProductList();
        }).catch((err) => {
          this.manageLogList.push(err.msg);
          if (this.tryCount > 0 && auto) {
            this.tryCount--;
            this.managePlatLogin(true);
          }
        });
    },
    // 获取验证码
    getCaptcha() {
      return new Promise((resolve, reject) => {
        this.$request.get(`${this.manageApiPre}/api/tiji-auth/oauth/captcha`).then(res => {
          let captchaRes = res.data;
          // 获取验证码图片
          var imgUrl = captchaRes.image;
          var img = new Image();
          img.src = imgUrl;
          // 当图片加载完成时执行  
          img.onload = async function () {
            var canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0);

            const worker = await createWorker('eng');
            // 直接使用tesseract.js对canvas进行OCR识别
            worker.recognize(
              canvas,
              'eng', // 指定OCR引擎使用的语言，这里是英文
              // {
              //   logger: m => console.log(m) // 定义一个日志函数来输出识别进度信息
              // }
            ).then(({ data: { text } }) => {
              // 识别完成，输出验证码文字
              let captchaCode = text.replaceAll(' ', '').replaceAll('\n', '');
              resolve({ captchaCodeUrl: captchaRes.image, captchaCode, uuid: captchaRes.key });
            }).catch(error => {
              // 识别过程中发生错误
              reject();
              console.error(error);
            });
          };
        }).catch(() => {
          reject();
        });
      });
    },
    //手动更新验证码
    refreshCaptcha() {
      if (!this.showCaptcha) { return; }
      this.$request.get(`${this.manageApiPre}/api/tiji-auth/oauth/captcha`).then(res => {
        let captchaRes = res.data;
        this.captchaCodeObj = {
          captchaCodeUrl: captchaRes.image,
          uuid: captchaRes.key
        };
      });
    },
    // 获取licence列表
    getLicenceList() {
      this.$request({
        url: `${this.manageApiPre}/api/license/page`,
        method: 'get',
        headers: {
          'tokenType': 'manage-token'
        },
        params: {
          enterpriseName: this.enterpriseName,
          current: 1,
          size: 1000,
          appType: 0
        }
      }).then(res => {
        this.manageLogList.push('成功获取licence列表');
        this.licenceList = res.data.data.records.map(v => {
          return {
            ...v,
            startTime: dayjs(v.authiorizationStartTime).format('YYYY-MM-DD'),
            endTime: dayjs(v.authiorizationEndTime).format('YYYY-MM-DD'),
          };
        });
      });
    },
    // 查看产品详情
    onProductInfo(id) {
      this.$request({
        url: `${this.manageApiPre}/api/license`,
        method: 'get',
        params: {
          id
        },
        headers: {
          'tokenType': 'manage-token'
        }
      }).then((res) => {
        const { data } = res;
        this.manageLogList.push('成功获取产品详情');
        this.checkedProduct = data.data.productList;
        this.$nextTick(() => {
          this.$refs.refProductInfo.init("查看产品", false);
        });
      });
    },
    // 下载licence
    onDown(id) {
      this.$request({
        url: `${this.manageApiPre}/api/license/export`,
        method: 'get',
        responseType: 'blob',
        timeout: 60000,
        headers: {
          'tokenType': 'manage-token'
        },
        params: {
          id
        }
      }).then((res) => {
        this.fileChange(res);
      });
    },
    //文件流转换成表格
    fileChange(res) {
      const link = document.createElement("a");
      let blob = new Blob([res.data], { type: "application/vnd.ms-excel" });
      link.style.display = "none";
      link.href = URL.createObjectURL(blob);
      // 省略代码
      let fileNameEncode = res.headers["content-disposition"].split(
        "filename="
      )[1]
        ? res.headers["content-disposition"].split("filename=")[1]
        : res.headers["content-disposition"].split("fileName=")[1];
      // 解码
      let fileName = decodeURIComponent(fileNameEncode);
      link.download = `${fileName}`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      this.manageLogList.push('licence文件下载成功');
    },
    // 获取产品列表
    getProductList() {
      this.$request({
        url: `${this.manageApiPre}/api/license/product/side-tree`,
        method: 'get',
        headers: {
          'tokenType': 'manage-token'
        }
      }).then(res => {
        this.productList = this.platTree(res.data.data);
        this.manageLogList.push('成功获取产品列表');
      });
    },
    // 拍平树形结构
    platTree(data) {
      // 将一个树形结构拍平
      let results = [];
      data.forEach(item => {
        // 开发环境会出现乱七八糟的id
        if (item.id && Number(item.id) > 0) {
          results.push(item);
        }
        if (item.children && item.children.length > 0) {
          results = results.concat(this.platTree(item.children));
        }
      });
      return results;
    },
    // 获取产品绑定的菜单code
    getBindMenuCodes() {
      this.$request({
        url: `${this.manageApiPre}/api/license/product/bind-menu`,
        method: 'get',
        params: {
          id: this.productId,
        },
        headers: {
          'tokenType': 'manage-token'
        }
      }).then(res => {
        let bindMenuList = this.platTree(res.data.data);
        this.bindMenuCodes = bindMenuList.filter(v => v.checked).map(item => item.menuCode);
        this.manageLogList.push('成功获取产品绑定的所有菜单codes');
      });
    },
    // 同步菜单
    asyncNewMenu() {
      this.$request({
        url: `${this.manageApiPre}/api/license/product/sync`,
        method: 'get',
        headers: {
          'tokenType': 'manage-token'
        }
      }).then(() => {
        this.manageLogList.push('菜单同步接口调用成功');
        // 获取产品绑定的菜单codes
        this.getBindMenuCodes();
        // 轮询菜单是否添加成功
        this.menuTimer = setInterval(() => {
          this.getNewMenu();
        }, 3000);
      });
    },
    // 查询菜单
    getNewMenu() {
      let appType = this.productList.find(v => v.id === this.productId).appType;
      this.$request({
        url: `${this.manageApiPre}/api/license/product/menu`,
        method: 'get',
        params: {
          id: this.productId,
          displayClient: 1, //web端菜单
          licenseAppType: appType
        },
        headers: {
          'tokenType': 'manage-token'
        }
      }).then(res => {
        this.manageLogList.push('菜单查询中...');
        let menuRes = res.data.data;
        let menuList = this.platTree(menuRes);
        // 拍平所有菜单，找到这次新增的菜单就停止定时器
        if (menuList.some(v => v.menuCode && this.newMenuCodes.includes(v.menuCode))) {
          this.manageLogList.push('菜单同步成功');
          this.clearTimer();
          this.bindMenu();
        }
      }).catch(() => {
        this.clearTimer();
      });
    },
    // 清除定时器
    clearTimer() {
      clearInterval(this.menuTimer);
      this.menuTimer = null;
    },
    // 添加菜单codes到产品
    bindMenu() {
      let menuCodes = [...new Set([...this.newMenuCodes, ...this.bindMenuCodes])];
      this.$request({
        url: `${this.manageApiPre}/api/license/product/bind`,
        method: 'post',
        data: {
          productId: this.productId,
          menuCodes
        },
        headers: {
          'tokenType': 'manage-token'
        }
      }).then(() => {
        this.manageLogList.push('成功添加菜单到产品');
      });
    },
    // 开始拖拽
    startDragging(e) {
      this.dragFlag = true;
      this.offsetX = e.clientX - this.posX;
      this.offsetY = e.clientY - this.posY;
    },
    // 拖拽中
    dragging(e) {
      // if (this.dragFlag) {
      //   this.posX = e.clientX - this.offsetX;
      //   this.posY = e.clientY - this.offsetY;
      // }
      if (this.dragFlag) {
        let posX = e.clientX - this.offsetX;
        let posY = e.clientY - this.offsetY;
        // 边界判断
        let MaxX = this.windowX - this.dragWidth;
        let MaxY = this.windowY - this.dragHeight;
        if (posX > 0 && posY > 0 && posX <= MaxX && posY <= MaxY) {
          this.posX = posX;
          this.posY = posY;
        }
      }
    },
    // 拖拽结束
    stopDragging() {
      this.dragFlag = false;
    }
  }
};
</script>

<style lang="scss" scoped>
.config-pic {
  background: #999;
  position: absolute;
  top: 20px;
  right: 20px;
}

.config-btns {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

.draggable {
  width: 640px;
  box-sizing: border-box;
  position: absolute;
  user-select: none;
  cursor: move;
  border: 1px solid #ccc;
  padding: 10px;
  background-color: #f0f0f0;

  .hide-btns {
    position: absolute;
    right: 10px;
    bottom: 10px;
  }

  .log-content {
    display: flex;

    >div {
      flex: 1;
      width: 0;
    }

    .log-title {
      font-weight: bold;
      margin: 12px 0;
    }

    .log-main {
      height: 300px;
      padding-bottom: 44px;
      box-sizing: border-box;
      overflow: auto;
    }
  }
}

.config-item {
  margin-bottom: 12px;
  display: flex;

  &.center {
    justify-content: center;
    align-items: center;
  }

  span {
    display: inline-block;
    width: 170px;
  }
}

:deep(.el-form) {

  .el-select,
  .el-input {
    width: 200px;
  }

  .row-del {
    margin-left: 20px;
  }
}
</style>
